package com.coffee.admin.service.common.impl;

import com.alibaba.fastjson.JSONObject;
import com.coffee.admin.api.common.query.AdminMenuQuery;
import com.coffee.admin.api.common.req.AdminMenuRequest;
import com.coffee.admin.api.common.result.AdminMenuResult;
import com.coffee.admin.api.common.result.CommonMenuResult;
import com.coffee.admin.api.common.service.AdminMenuService;
import com.coffee.admin.api.platform.service.PlatformPermissionService;
import com.coffee.admin.api.supplier.service.SupplierPermissionService;
import com.coffee.admin.service.common.bean.AdminMenu;
import com.coffee.admin.service.common.dao.AdminMenuDao;
import com.coffee.admin.service.platform.bean.Platform;
import com.coffee.admin.service.platform.dao.PlatformDao;
import com.coffee.admin.service.supplier.bean.Supplier;
import com.coffee.admin.service.supplier.dao.SupplierDao;
import com.coffee.core.entity.Page;
import com.coffee.core.entity.PagerInfo;
import com.coffee.core.enums.ExceptionEnum;
import com.coffee.core.enums.RoleTypeEnum;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.util.BeanUtilExt;
import com.coffee.core.util.DTOUtils;
import com.coffee.core.util.StringUtil;
import com.coffee.daili.api.query.DailiMerchantQuery;
import com.coffee.daili.service.bean.DailiMerchant;
import com.coffee.daili.service.dao.DailiMerchantDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@DubboService(dynamic = true)
public class AdminMenuServiceImpl implements AdminMenuService {
    private final static Logger logger = LoggerFactory.getLogger(AdminMenuServiceImpl.class);
    @Resource
    private AdminMenuDao adminMenuDao;
    @Resource
    private SupplierDao supplierDao;
    @Resource
    private DailiMerchantDao dailiMerchantDao;
    @Resource
    private PlatformDao platformDao;
    @DubboReference
    private SupplierPermissionService supplierPermissionService;
    @DubboReference
    private PlatformPermissionService platformPermissionService;

    @Override
    public Page<AdminMenuResult> getPager(AdminMenuQuery param, PagerInfo pr) {
        Page<AdminMenuResult> pager = new Page<AdminMenuResult>(pr.getStart(), pr.getPageSize());
        Integer count = adminMenuDao.count(param);
        pager.setTotalPage(count);
        if (count > 0) {
            List<AdminMenu> list = adminMenuDao.page(param, pr.getStart(), pr.getPageSize());
            pager.setData(DTOUtils.convertList(list, AdminMenuResult.class));
        }
        return pager;
    }

    @Override
    public Integer count(AdminMenuQuery param) {
        Integer count = adminMenuDao.count(param);
        return count;
    }

    @Override
    public AdminMenuResult getDetail(Integer id) {
        AdminMenu item = adminMenuDao.findById(id);
        if (item == null) {
            return null;
        }
        AdminMenuResult result = new AdminMenuResult();
        BeanUtilExt.copyProperties(result, item);

        return result;
    }

    @Override
    public List<AdminMenuResult> getList(AdminMenuQuery param, PagerInfo pr) {
        List<AdminMenu> list = adminMenuDao.page(param, pr.getStart(), pr.getPageSize());
        return DTOUtils.convertList(list, AdminMenuResult.class);
    }

    @Override
    public List<AdminMenuResult> getList(AdminMenuQuery param) {
        List<AdminMenu> list = adminMenuDao.page(param, 0, Integer.MAX_VALUE);
        return DTOUtils.convertList(list, AdminMenuResult.class);
    }

    @Override
    public List<AdminMenuResult> getList() {
        AdminMenuQuery param = new AdminMenuQuery();
        List<AdminMenu> list = adminMenuDao.page(param, 0, Integer.MAX_VALUE);
        return DTOUtils.convertList(list, AdminMenuResult.class);
    }


    @Override
    public void delete(Integer id) {
        adminMenuDao.deleteById(id);
    }

    @Override
    public void addOrUpdate(AdminMenuResult result) throws BusinessException {
        AdminMenu item = new AdminMenu();
        BeanUtilExt.copyProperties(item, result);
        if (item.getId() == null) {
            item.setCreateTime(new Date());
            adminMenuDao.insert(item);
        } else {
            AdminMenu tmp = adminMenuDao.findById(item.getId());
            if (tmp == null) {
                throw new BusinessException(ExceptionEnum.ERROR_0002.getCode(), ExceptionEnum.ERROR_0002.getMessage());
            }
            adminMenuDao.updateById(item);
        }
    }

    @Override
    public Map<Integer, AdminMenuResult> getItemMap(Set<Integer> idSet) {
        Map<Integer, AdminMenuResult> map = new HashMap<Integer, AdminMenuResult>();
        List<AdminMenu> list = adminMenuDao.findByIds(StringUtil.setToList(idSet));
        List<AdminMenuResult> resultList = DTOUtils.convertList(list, AdminMenuResult.class);
        for (AdminMenuResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public Map<Integer, AdminMenuResult> getItemMap() {
        Map<Integer, AdminMenuResult> map = new HashMap<Integer, AdminMenuResult>();
        AdminMenuQuery param = new AdminMenuQuery();
        List<AdminMenu> list = adminMenuDao.page(param, 0, Integer.MAX_VALUE);
        List<AdminMenuResult> resultList = DTOUtils.convertList(list, AdminMenuResult.class);
        for (AdminMenuResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public CommonMenuResult supplierList(AdminMenuRequest request) throws BusinessException {
        CommonMenuResult commonMenuResult = new CommonMenuResult();
        logger.info("request===" + JSONObject.toJSONString(request));
        if (request.getSupplierUserId() != null) {
            Integer operatorId = request.getSupplierUserId();
            Supplier supplier = supplierDao.findById(operatorId);
            if (supplier != null && "Y".equals(supplier.getIsEnable())) {
                String groupCode = RoleTypeEnum.SUPPLIER.getCode();
                List<AdminMenu> adminMenuList = new ArrayList<>();
                AdminMenuQuery query = new AdminMenuQuery();
                query.setGroupCode(groupCode);
                if ("Y".equals(request.getSupplierIsAdmin())) {
                    //管理员菜单
                    List<AdminMenu> adminMenu = adminMenuDao.list(query);
                    adminMenuList.addAll(adminMenu);
                } else {
                    Set<String> permissionSet = supplierPermissionService.getPermissionSet(operatorId);
                    logger.info("permissionSet===" + JSONObject.toJSONString(permissionSet));
                    if (CollectionUtils.isNotEmpty(permissionSet)) {
                        query.setAliasSet(permissionSet);
                        List<AdminMenu> adminMenus = adminMenuDao.list(query);
                        adminMenuList.addAll(adminMenus);
                    }
                }
                Supplier adminSupplier = supplierDao.findById(request.getSupplierId());
                if (adminSupplier != null) {
                    DailiMerchantQuery param = new DailiMerchantQuery();
                    param.setMobile(adminSupplier.getMobile());
                    DailiMerchant dailiMerchant = dailiMerchantDao.findFirst(param);
                    if (dailiMerchant == null) {
                        Iterator<AdminMenu> iterator = adminMenuList.iterator();
                        while (iterator.hasNext()) {
                            AdminMenu next = iterator.next();
                            if (next.getMenuName().equals("城市合伙人") || next.getMenuName().equals("分销商品")) {
                                iterator.remove();
                            }
                        }
                    }
                }
                //分组
                Map<Integer, List<AdminMenu>> groupListMap = adminMenuList.stream().collect(Collectors.groupingBy(AdminMenu::getParentMenuId));
                List<AdminMenu> adminMenus = groupListMap.get(0);
                List<AdminMenuResult> adminMenuResults = DTOUtils.convertList(adminMenus, AdminMenuResult.class);

                recursion(groupListMap, adminMenuResults);

                commonMenuResult.setSupplierList(adminMenuResults);
            }
        }

        if (request.getPlatformUserId() != null) {
            Integer operatorId = request.getPlatformUserId();
            Platform platform = platformDao.findById(operatorId);
            if (platform != null && "Y".equals(platform.getIsEnable())) {
                String groupCode = RoleTypeEnum.PLATFORM.getCode();
                List<AdminMenu> adminMenuList = new ArrayList<>();
                AdminMenuQuery query = new AdminMenuQuery();
                query.setGroupCode(groupCode);
                if ("Y".equals(request.getPlatformIsAdmin())) {
                    //管理员菜单
                    List<AdminMenu> adminMenu = adminMenuDao.list(query);
                    adminMenuList.addAll(adminMenu);
                } else {
                    Set<String> permissionSet = platformPermissionService.getPermissionSet(operatorId);
                    if (CollectionUtils.isNotEmpty(permissionSet)) {
                        query.setAliasSet(permissionSet);
                        List<AdminMenu> adminMenus = adminMenuDao.list(query);
                        adminMenuList.addAll(adminMenus);
                    }
                }
                //分组
                Map<Integer, List<AdminMenu>> groupListMap = adminMenuList.stream().collect(Collectors.groupingBy(AdminMenu::getParentMenuId));
                List<AdminMenu> adminMenus = groupListMap.get(0);
                List<AdminMenuResult> adminMenuResults = DTOUtils.convertList(adminMenus, AdminMenuResult.class);
                recursion(groupListMap, adminMenuResults);
                commonMenuResult.setPlatformList(adminMenuResults);
            }
        }
        return commonMenuResult;
    }


    public void recursion(Map<Integer, List<AdminMenu>> groupListMap, List<AdminMenuResult> adminMenuResults) {
        for (AdminMenuResult adminMenuResult : adminMenuResults) {
            Integer id = adminMenuResult.getId();
            List<AdminMenu> adminMenus = groupListMap.get(id);
            if (CollectionUtils.isNotEmpty(adminMenus)) {
                List<AdminMenuResult> submenuList = DTOUtils.convertList(adminMenus, AdminMenuResult.class);
                recursion(groupListMap, submenuList);
                adminMenuResult.setSubmenuList(submenuList);
            }
        }
    }


}
